package org.example.gateway.config;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.oauth2.common.DefaultOAuth2AccessToken;
import org.springframework.security.oauth2.provider.OAuth2Authentication;
import org.springframework.security.oauth2.provider.token.TokenStore;
import org.springframework.security.oauth2.provider.token.store.JwtAccessTokenConverter;
import org.springframework.security.oauth2.provider.token.store.JwtTokenStore;

import java.util.HashMap;
import java.util.Map;

/**
 * 令牌相关配置类
 */
@Configuration
public class JwtTokenStoreConfiguration {

    /**
     * 不同的系统用不同的jwtKey；不推荐共用一样的
     * <p>
     * HMAC key, default: IH6S2dhCEMwGr7uE4fBakSuDh9SoIrRa
     * alg: HMACSHA256
     */
    @Value("${sos.token.store.jwt.key:IH6S2dhCEMwGr7uE4fBakSuDh9SoIrRa}")
    private String jwtKey;
    /**
     * 是否重复使用已经有的 refresh_token 直到过期，默认true
     */
    @Value("${sos.reuse.refresh-token:true}")
    private boolean reuseRefreshToken;

    @Bean
    public TokenStore tokenStore() {
        return new JwtTokenStore(jwtAccessTokenConverter());
    }


    @Bean
    public JwtAccessTokenConverter jwtAccessTokenConverter() {
        JwtAccessTokenConverter jwtAccessTokenConverter = new JwtAccessTokenEnhancer();
        jwtAccessTokenConverter.setSigningKey(this.jwtKey);
        return jwtAccessTokenConverter;
    }





    /**
     * JWT令牌增强，继承JwtAccessTokenConverter
     * 将业务所需的额外信息放入令牌中，这样下游微服务就能解析令牌获取
     */
    public static class JwtAccessTokenEnhancer extends JwtAccessTokenConverter {
        /**
         * 重写enhance方法，在其中扩展
         */
        @Override
        public org.springframework.security.oauth2.common.OAuth2AccessToken enhance(org.springframework.security.oauth2.common.OAuth2AccessToken accessToken, OAuth2Authentication authentication) {
            Map<String, Object> info = new HashMap<>();
            //我们需要增强的内容
            info.put("enhance", "enhance info");
            ((DefaultOAuth2AccessToken) accessToken).setAdditionalInformation(info);
            return super.enhance(accessToken, authentication);
        }
    }

}
